#include "mqclientconfigdialog.h"
#include "ui_mqclientconfig.h"
#include "mqclient.h"
#include <QMessageBox>
#include <QFileDialog>
#include <QStandardPaths>
#include <QLoggingCategory>
#include <QTimer>
#include <QApplication>
#include <QStyle>
#include <QThread>
#include <QMetaObject>
#include <QPointer>


Q_LOGGING_CATEGORY(configdialog, "configdialog")

/**
 * @brief MQClientConfigDialog构造函数
 * @param parent 父窗口
 */
MQClientConfigDialog::MQClientConfigDialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::MQClientConfigDialog)
    , m_testTimer(new QTimer(this))
    , m_configChanged(false)
{
    ui->setupUi(this);
    
    // 设置窗口属性
    setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
    setModal(true);
    
    // 初始化UI
    initializeUI();
    
    // 连接信号和槽
    connectSignals();
    
    // 从配置管理器加载配置
    MQConfigManager* configManager = MQConfigManager::getInstance();
    MQConfig config = configManager->getConfig();
    
    m_originalConnectionConfig = config.connection;
    m_originalBusinessConfig = config.business;
    
    // 应用配置到UI
    applyConnectionConfigToUI(m_originalConnectionConfig);
    applyBusinessConfigToUI(m_originalBusinessConfig);
    
    // 设置测试连接超时
    m_testTimer->setSingleShot(true);
    m_testTimer->setInterval(10000); // 10秒超时
    connect(m_testTimer, &QTimer::timeout, this, &MQClientConfigDialog::onTestTimeout);
    
    qCDebug(configdialog) << "配置对话框已创建";
}

/**
 * @brief MQClientConfigDialog析构函数
 */
MQClientConfigDialog::~MQClientConfigDialog()
{
    delete ui;
    qCDebug(configdialog) << "配置对话框已销毁";
}

/**
 * @brief 初始化UI
 */
void MQClientConfigDialog::initializeUI()
{
    // 设置默认值
    ui->hostnameEdit->setText("192.168.10.162");
    ui->portSpinBox->setValue(5672);
    ui->usernameEdit->setText("guest");
    ui->passwordEdit->setText("guest");
    ui->vhostEdit->setText("/");
    
    // 设置状态标签样式
    updateStatus("就绪", false);
    
    // 设置工具提示
    ui->hostnameEdit->setToolTip("RabbitMQ服务器的主机名或IP地址");
    ui->portSpinBox->setToolTip("RabbitMQ服务器的端口号，默认为5672");
    ui->usernameEdit->setToolTip("连接RabbitMQ的用户名");
    ui->passwordEdit->setToolTip("连接RabbitMQ的密码");
    ui->vhostEdit->setToolTip("RabbitMQ的虚拟主机，默认为/");
    
    // 性能配置、可靠性配置和日志配置已硬编码，移除相关工具提示
    
    // 业务配置默认值和工具提示
    ui->exchangeNameEdit->setText("test_exchange");
    ui->exchangeTypeComboBox->setCurrentText("direct");
    ui->exchangeDurableCheckBox->setChecked(true);
    
    ui->queueNameEdit->setText("test_queue");
    ui->queueDurableCheckBox->setChecked(true);
    ui->queueExclusiveCheckBox->setChecked(false);
    ui->queueAutoDeleteCheckBox->setChecked(false);
    
    ui->routingKeyEdit->setText("agv.task.execute");
    ui->queueRoutingKeyEdit->setText("agv.task.*");
    
    // 业务配置工具提示
    ui->exchangeNameEdit->setToolTip("默认交换机的名称");
    ui->exchangeTypeComboBox->setToolTip("交换机类型：direct(直连)、fanout(广播)、topic(主题)、headers(头部)");
    ui->exchangeDurableCheckBox->setToolTip("是否创建持久化交换机，重启后仍然存在");
    
    ui->queueNameEdit->setToolTip("默认队列的名称");
    ui->queueDurableCheckBox->setToolTip("是否创建持久化队列，重启后仍然存在");
    ui->queueExclusiveCheckBox->setToolTip("是否创建独占队列，只能被当前连接使用");
    ui->queueAutoDeleteCheckBox->setToolTip("是否自动删除队列，当没有消费者时自动删除");
    
    ui->routingKeyEdit->setToolTip("发布消息时使用的路由键");
    ui->queueRoutingKeyEdit->setToolTip("绑定队列到交换机时使用的路由键，支持通配符（*匹配一个单词，#匹配零个或多个单词）");
    
    qCDebug(configdialog) << "UI初始化完成";
}

/**
 * @brief 连接信号和槽
 */
void MQClientConfigDialog::connectSignals()
{
    // 按钮信号
    connect(ui->testConnectionButton, &QPushButton::clicked, this, &MQClientConfigDialog::testConnection);
    connect(ui->loadDefaultButton, &QPushButton::clicked, this, &MQClientConfigDialog::loadDefaultConfig);
    connect(ui->applyButton, &QPushButton::clicked, this, &MQClientConfigDialog::applyConfig);
    // 日志配置已硬编码，移除browseLogFile相关功能
    
    // 配置改变信号
    connect(ui->hostnameEdit, &QLineEdit::textChanged, this, &MQClientConfigDialog::onConfigChanged);
    connect(ui->portSpinBox, QOverload<int>::of(&QSpinBox::valueChanged), this, &MQClientConfigDialog::onConfigChanged);
    connect(ui->usernameEdit, &QLineEdit::textChanged, this, &MQClientConfigDialog::onConfigChanged);
    connect(ui->passwordEdit, &QLineEdit::textChanged, this, &MQClientConfigDialog::onConfigChanged);
    connect(ui->vhostEdit, &QLineEdit::textChanged, this, &MQClientConfigDialog::onConfigChanged);
    
    // 性能配置、可靠性配置和日志配置已硬编码，移除相关信号连接
    
    // 业务配置信号
    connect(ui->exchangeNameEdit, &QLineEdit::textChanged, this, &MQClientConfigDialog::onConfigChanged);
    connect(ui->exchangeTypeComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &MQClientConfigDialog::onConfigChanged);
    connect(ui->exchangeDurableCheckBox, &QCheckBox::toggled, this, &MQClientConfigDialog::onConfigChanged);
    
    connect(ui->queueNameEdit, &QLineEdit::textChanged, this, &MQClientConfigDialog::onConfigChanged);
    connect(ui->queueDurableCheckBox, &QCheckBox::toggled, this, &MQClientConfigDialog::onConfigChanged);
    connect(ui->queueExclusiveCheckBox, &QCheckBox::toggled, this, &MQClientConfigDialog::onConfigChanged);
    connect(ui->queueAutoDeleteCheckBox, &QCheckBox::toggled, this, &MQClientConfigDialog::onConfigChanged);
    
    connect(ui->routingKeyEdit, &QLineEdit::textChanged, this, &MQClientConfigDialog::onConfigChanged);
    connect(ui->queueRoutingKeyEdit, &QLineEdit::textChanged, this, &MQClientConfigDialog::onConfigChanged);
    
    qCDebug(configdialog) << "信号连接完成";
}

/**
 * @brief 获取连接配置
 * @return 连接配置对象
 */
MQConnectionConfig MQClientConfigDialog::getConnectionConfig() const
{
    return loadConnectionConfigFromUI();
}

/**
 * @brief 设置连接配置
 * @param config 连接配置对象
 */
void MQClientConfigDialog::setConnectionConfig(const MQConnectionConfig& config)
{
    applyConnectionConfigToUI(config);
    m_originalConnectionConfig = config;
    m_configChanged = false;
}

/**
 * @brief 获取业务配置
 * @return 业务配置对象
 */
MQBusinessConfig MQClientConfigDialog::getBusinessConfig() const
{
    return loadBusinessConfigFromUI();
}

/**
 * @brief 设置业务配置
 * @param config 业务配置对象
 */
void MQClientConfigDialog::setBusinessConfig(const MQBusinessConfig& config)
{
    applyBusinessConfigToUI(config);
    m_originalBusinessConfig = config;
    m_configChanged = false;
}

/**
 * @brief 测试连接
 */
void MQClientConfigDialog::testConnection()
{
    updateStatus("正在测试连接...", false);
    setUIEnabled(false);
    
    // 获取当前连接配置
    MQConnectionConfig config = loadConnectionConfigFromUI();
    
    // 验证连接配置
    auto validation = validateConnectionConfig(config);
    if (!validation.first) {
        updateStatus(QString("配置验证失败: %1").arg(validation.second), true);
        setUIEnabled(true);
        return;
    }
    
    // 启动超时定时器
    m_testTimer->start();
    
    // 在工作线程中进行连接测试，避免阻塞UI
    QThread* testThread = new QThread(this);
    QObject* worker = new QObject();
    worker->moveToThread(testThread);
    
    // 连接信号槽
    connect(testThread, &QThread::started, worker, [this, config, worker, testThread]() {
        qCDebug(configdialog) << "开始在工作线程中测试连接";
        
        // 创建临时连接进行测试
        amqp_connection_state_t testConn = amqp_new_connection();
        bool success = false;
        QString errorMsg;
        
        if (testConn) {
            // 创建套接字
            amqp_socket_t *socket = amqp_tcp_socket_new(testConn);
            if (socket) {
                // 尝试连接
                int status = amqp_socket_open(socket, 
                                             config.hostname.toUtf8().constData(), 
                                             config.port);
                if (status == AMQP_STATUS_OK) {
                    // 尝试登录
                    amqp_rpc_reply_t reply = amqp_login(testConn, 
                                                      config.vhost.toUtf8().constData(),
                                                      0, 131072, 60,
                                                      AMQP_SASL_METHOD_PLAIN,
                                                      config.username.toUtf8().constData(),
                                                      config.password.toUtf8().constData());
                    if (reply.reply_type == AMQP_RESPONSE_NORMAL) {
                        success = true;
                    } else {
                        errorMsg = "登录失败";
                    }
                } else {
                    errorMsg = QString("无法打开TCP套接字连接: %1").arg(status);
                }
            } else {
                errorMsg = "无法创建TCP套接字";
            }
            
            // 清理连接
            amqp_destroy_connection(testConn);
        } else {
            errorMsg = "无法创建RabbitMQ连接";
        }
        
        // 在主线程中更新UI
        QMetaObject::invokeMethod(this, [this, success, errorMsg]() {
            m_testTimer->stop();
            setUIEnabled(true);
            
            if (success) {
                updateStatus("连接测试成功", false);
                QMessageBox::information(this, "测试结果", "连接测试成功！");
            } else {
                updateStatus(QString("连接测试失败: %1").arg(errorMsg), true);
                QMessageBox::warning(this, "测试结果", QString("连接测试失败: %1").arg(errorMsg));
            }
        }, Qt::QueuedConnection);
        
        // 清理工作线程
        worker->deleteLater();
        testThread->quit();
        testThread->deleteLater();
    });
    
    testThread->start();
    qCDebug(configdialog) << "开始测试连接";
}

/**
 * @brief 加载默认配置
 */
void MQClientConfigDialog::loadDefaultConfig()
{
    // 连接配置默认值
    MQConnectionConfig defaultConnectionConfig;
    defaultConnectionConfig.hostname = "192.168.10.162";
    defaultConnectionConfig.port = 5672;
    defaultConnectionConfig.username = "guest";
    defaultConnectionConfig.password = "guest";
    defaultConnectionConfig.vhost = "/";
    // 技术参数已在MQClient::connectInternal中硬编码
    
    // 业务配置默认值
    MQBusinessConfig defaultBusinessConfig;
    defaultBusinessConfig.defaultExchange.name = "default_exchange";
    defaultBusinessConfig.defaultExchange.type = "direct";
    defaultBusinessConfig.defaultExchange.durable = true;
    
    defaultBusinessConfig.defaultQueue.name = "default_queue";
    defaultBusinessConfig.defaultQueue.durable = true;
    defaultBusinessConfig.defaultQueue.exclusive = false;
    defaultBusinessConfig.defaultQueue.autoDelete = false;
    
    defaultBusinessConfig.defaultBinding.routingKey = "default_key";
    
    applyConnectionConfigToUI(defaultConnectionConfig);
    applyBusinessConfigToUI(defaultBusinessConfig);
    updateStatus("已加载默认配置", false);
    
    qCDebug(configdialog) << "已加载默认配置";
}

/**
 * @brief 应用配置
 */
void MQClientConfigDialog::applyConfig()
{
    try {
        // 获取连接配置和业务配置
        MQConnectionConfig connectionConfig = loadConnectionConfigFromUI();
        MQBusinessConfig businessConfig = loadBusinessConfigFromUI();

        // 验证连接配置
        auto connectionValidation = validateConnectionConfig(connectionConfig);
        if (!connectionValidation.first) {
            QMessageBox::warning(this, "配置错误", connectionValidation.second);
            return;
        }

        // 验证业务配置
        auto businessValidation = validateBusinessConfig(businessConfig);
        if (!businessValidation.first) {
            QMessageBox::warning(this, "配置错误", businessValidation.second);
            return;
        }

        // 保存配置到配置管理器
        MQConfigManager* configManager = MQConfigManager::getInstance();
        if (!configManager) {
            QMessageBox::critical(this, "错误", "无法获取配置管理器实例！");
            return;
        }

        MQConfig config;
        config.connection = connectionConfig;
        config.business = businessConfig;

        // 使用QPointer确保对象安全访问
        QPointer<MQClientConfigDialog> self(this);

        // 使用QTimer::singleShot延迟设置配置，避免信号处理中的竞态条件
        QTimer::singleShot(0, [self, configManager, config]() {
            // 检查对象是否仍然有效
            if (!self) {
                qCWarning(configdialog) << "对话框已销毁，跳过配置保存后处理";
                return;
            }

            try {
                configManager->setConfig(config);

                // 保存到文件
                if (configManager->saveConfig()) {
                    // 更新原始配置
                    self->m_originalConnectionConfig = config.connection;
                    self->m_originalBusinessConfig = config.business;
                    self->m_configChanged = false;

                    self->updateStatus("配置已保存", false);
                    QMessageBox::information(self, "成功", "配置已成功保存到文件！");

                    qCDebug(configdialog) << "配置已保存到文件";
                } else {
                    self->updateStatus("配置保存失败", true);
                    QMessageBox::warning(self, "错误", "配置保存到文件失败！");
                }
            } catch (const std::exception& e) {
                self->updateStatus("配置保存异常", true);
                QMessageBox::critical(self, "异常", QString("配置保存过程中发生异常: %1").arg(e.what()));
                qCCritical(configdialog) << "配置保存异常:" << e.what();
            } catch (...) {
                self->updateStatus("配置保存异常", true);
                QMessageBox::critical(self, "异常", "配置保存过程中发生未知异常！");
                qCCritical(configdialog) << "配置保存过程中发生未知异常";
            }
        });

    } catch (const std::exception& e) {
        updateStatus("配置应用异常", true);
        QMessageBox::critical(this, "异常", QString("配置应用过程中发生异常: %1").arg(e.what()));
        qCCritical(configdialog) << "配置应用异常:" << e.what();
    } catch (...) {
        updateStatus("配置应用异常", true);
        QMessageBox::critical(this, "异常", "配置应用过程中发生未知异常！");
        qCCritical(configdialog) << "配置应用过程中发生未知异常";
    }
}

/**
 * @brief 浏览日志文件（已废弃，日志配置已硬编码）
 */
// browseLogFile方法已移除，日志配置已硬编码

/**
 * @brief 配置项改变时的处理
 */
void MQClientConfigDialog::onConfigChanged()
{
    m_configChanged = true;
    ui->applyButton->setEnabled(true);
    updateStatus("配置已修改", false);
}

/**
 * @brief 接受对话框时的处理
 */
void MQClientConfigDialog::accept()
{
    if (m_configChanged) {
        int ret = QMessageBox::question(
            this,
            "保存配置",
            "配置已修改，是否保存？",
            QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel
        );
        
        if (ret == QMessageBox::Save) {
            applyConfig();
        } else if (ret == QMessageBox::Cancel) {
            return;
        }
    }
    
    QDialog::accept();
}

/**
 * @brief 拒绝对话框时的处理
 */
void MQClientConfigDialog::reject()
{
    if (m_configChanged) {
        int ret = QMessageBox::question(
            this,
            "放弃更改",
            "配置已修改，是否放弃更改？",
            QMessageBox::Yes | QMessageBox::No
        );
        
        if (ret == QMessageBox::No) {
            return;
        }
    }
    
    QDialog::reject();
}

/**
 * @brief 测试连接超时处理
 */
void MQClientConfigDialog::onTestTimeout()
{
    updateStatus("连接测试超时", true);
    setUIEnabled(true);
    
    QMessageBox::warning(this, "测试失败", "连接测试超时，请检查配置和网络连接。");
    
    qCWarning(configdialog) << "连接测试超时";
}

/**
 * @brief 从UI加载连接配置
 * @return 连接配置对象
 */
MQConnectionConfig MQClientConfigDialog::loadConnectionConfigFromUI() const
{
    MQConnectionConfig config;
    
    config.hostname = ui->hostnameEdit->text().trimmed();
    config.port = ui->portSpinBox->value();
    config.username = ui->usernameEdit->text().trimmed();
    config.password = ui->passwordEdit->text();
    config.vhost = ui->vhostEdit->text().trimmed();
    // 技术参数已在MQClient::connectInternal中硬编码
    
    return config;
}

/**
 * @brief 从UI加载业务配置
 * @return 业务配置对象
 */
MQBusinessConfig MQClientConfigDialog::loadBusinessConfigFromUI() const
{
    MQBusinessConfig config;
    
    config.defaultExchange.name = ui->exchangeNameEdit->text().trimmed();
    config.defaultExchange.type = ui->exchangeTypeComboBox->currentText();
    config.defaultExchange.durable = ui->exchangeDurableCheckBox->isChecked();
    
    config.defaultQueue.name = ui->queueNameEdit->text().trimmed();
    config.defaultQueue.durable = ui->queueDurableCheckBox->isChecked();
    config.defaultQueue.exclusive = ui->queueExclusiveCheckBox->isChecked();
    config.defaultQueue.autoDelete = ui->queueAutoDeleteCheckBox->isChecked();
    
    config.defaultBinding.routingKey = ui->routingKeyEdit->text().trimmed();
    config.defaultBinding.queue_routing_key = ui->queueRoutingKeyEdit->text().trimmed();
    
    return config;
}

/**
 * @brief 将连接配置应用到UI
 * @param config 连接配置对象
 */
void MQClientConfigDialog::applyConnectionConfigToUI(const MQConnectionConfig& config)
{
    ui->hostnameEdit->setText(config.hostname);
    ui->portSpinBox->setValue(config.port);
    ui->usernameEdit->setText(config.username);
    ui->passwordEdit->setText(config.password);
    ui->vhostEdit->setText(config.vhost);
    
    m_configChanged = false;
}

/**
 * @brief 将业务配置应用到UI
 * @param config 业务配置对象
 */
void MQClientConfigDialog::applyBusinessConfigToUI(const MQBusinessConfig& config)
{
    ui->exchangeNameEdit->setText(config.defaultExchange.name);
    
    // 设置交换机类型
    int exchangeTypeIndex = ui->exchangeTypeComboBox->findText(config.defaultExchange.type, Qt::MatchFixedString);
    if (exchangeTypeIndex >= 0) {
        ui->exchangeTypeComboBox->setCurrentIndex(exchangeTypeIndex);
    }
    ui->exchangeDurableCheckBox->setChecked(config.defaultExchange.durable);
    
    ui->queueNameEdit->setText(config.defaultQueue.name);
    ui->queueDurableCheckBox->setChecked(config.defaultQueue.durable);
    ui->queueExclusiveCheckBox->setChecked(config.defaultQueue.exclusive);
    ui->queueAutoDeleteCheckBox->setChecked(config.defaultQueue.autoDelete);
    
    ui->routingKeyEdit->setText(config.defaultBinding.routingKey);
    ui->queueRoutingKeyEdit->setText(config.defaultBinding.queue_routing_key);
    
    m_configChanged = false;
}

/**
 * @brief 验证连接配置
 * @param config 要验证的连接配置
 * @return 验证结果和错误信息
 */
QPair<bool, QString> MQClientConfigDialog::validateConnectionConfig(const MQConnectionConfig& config) const
{
    // 验证主机名
    if (config.hostname.isEmpty()) {
        return QPair<bool, QString>(false, "主机名不能为空");
    }
    
    // 验证端口
    if (config.port < 1 || config.port > 65535) {
        return QPair<bool, QString>(false, "端口号必须在1-65535之间");
    }
    
    // 验证用户名
    if (config.username.isEmpty()) {
        return QPair<bool, QString>(false, "用户名不能为空");
    }
    
    // 验证虚拟主机
    if (config.vhost.isEmpty()) {
        return QPair<bool, QString>(false, "虚拟主机不能为空");
    }
    
    return QPair<bool, QString>(true, QString());
}

/**
 * @brief 验证业务配置
 * @param config 要验证的业务配置
 * @return 验证结果和错误信息
 */
QPair<bool, QString> MQClientConfigDialog::validateBusinessConfig(const MQBusinessConfig& config) const
{
    // 验证交换机名称
    if (config.defaultExchange.name.isEmpty()) {
        return QPair<bool, QString>(false, "交换机名称不能为空");
    }
    
    // 验证队列名称
    if (config.defaultQueue.name.isEmpty()) {
        return QPair<bool, QString>(false, "队列名称不能为空");
    }
    
    // 验证发布路由键
    if (config.defaultBinding.routingKey.isEmpty()) {
        return QPair<bool, QString>(false, "发布路由键不能为空");
    }
    
    // 验证队列绑定路由键
    if (config.defaultBinding.queue_routing_key.isEmpty()) {
        return QPair<bool, QString>(false, "队列绑定路由键不能为空");
    }
    
    return QPair<bool, QString>(true, QString());
}

/**
 * @brief 更新状态标签
 * @param message 状态消息
 * @param isError 是否为错误状态
 */
void MQClientConfigDialog::updateStatus(const QString& message, bool isError)
{
    ui->statusLabel->setText(QString("状态: %1").arg(message));
    
    if (isError) {
        ui->statusLabel->setStyleSheet("color: red;");
    } else {
        ui->statusLabel->setStyleSheet("color: green;");
    }
}

/**
 * @brief 设置UI启用状态
 * @param enabled 是否启用
 */
void MQClientConfigDialog::setUIEnabled(bool enabled)
{
    ui->tabWidget->setEnabled(enabled);
    ui->testConnectionButton->setEnabled(enabled);
    ui->loadDefaultButton->setEnabled(enabled);
    ui->applyButton->setEnabled(enabled && m_configChanged);
    ui->okButton->setEnabled(enabled);
    ui->cancelButton->setEnabled(enabled);
}
